home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / m2 / cat3src / cat / printer.i < prev    next >
Text File  |  1997-10-26  |  18KB  |  652 lines

  1. IMPLEMENTATION MODULE Printer;
  2. (*****************************************************************************
  3.   Projekt:
  4.   Datei  : PRINTER.M
  5.   Datum  : 21.12.1991
  6.   Autor  : Uwe Mindrup, Wolfsgrubenstraže 23, 74379 Ingersheim, Tel: 07142/64385
  7.            Uwe Mindrup @ S3
  8. ******************************************************************************)
  9.  
  10. FROM SYSTEM IMPORT ADDRESS, ADR;
  11. IMPORT Storage, 
  12.        CatGlobal,    (* vorher: FSelect *)
  13.        MagicDOS,     (* vorher: MagicDOS, *)
  14.                      (* Streams, ebenfalls durch direkt MagicDOS-Calls ersetzt *)
  15.        Strings,      (* vorher: String *)
  16.        SysVars,      (* vorher: SysVar *)
  17.        SysUtil1;
  18.  
  19. TYPE   tTableEntry = RECORD
  20.                        len,
  21.                        pos  : SHORTINT;
  22.                      END;
  23.  
  24. CONST cMaxSequence     = 4FH;
  25.       cMaxTranslations = 0FFH;
  26.       (* es folgen die Konstanten fr den Tabelleneingang der Funktionen: *)
  27.       cVertPos         = 5;      (* absolute vertikale Positionierung *)
  28.       cBold            = 6;
  29.       cItalic          = 0AH;
  30.       cLight           = 0EH;
  31.       cSuperscript     = 12H;
  32.       cSubscript       = 16H;
  33.       cUnderline       = 1AH;
  34.       cHorzInit        = 1FH;
  35.       cVertInit        = 20H;
  36.       cPrinterInit     = 21H;
  37.  
  38.       c1stType         = 28H;
  39.       c1stColor        = 30H;
  40.       cProp            = 35H;
  41.       cFormFeed        = 1EH;
  42.       cWriteLn         = 1;
  43.       cTab             = 11C;
  44.  
  45. VAR
  46.     SeqTable     : ARRAY[0..cMaxSequence]     OF tTableEntry;
  47.     TransTable   : ARRAY[0..cMaxTranslations] OF tTableEntry;
  48.     CFG          : POINTER TO ARRAY [0..MAX(SHORTINT)] OF CHAR;
  49.     TabSize      : SHORTINT;
  50.     NLQSet       : SHORTINT; (* [0..2] *)
  51.     CharPos,                 (* Position des Zeichens in der aktuellen Zeile *)
  52.     NrSpaces,                (* Anzahl Leerzeichen *)
  53.     PropSize     : SHORTINT;
  54.     PrnHdl       : SHORTINT;
  55.     Proportional : BOOLEAN;
  56.     AktColor,
  57.     AktMode      : SHORTINT;
  58.  
  59. (* Ersatz fr das Streams-Modul: Die Variablen *)
  60. VAR currentOut   : SHORTINT;     (* Das Handle des Kanals *)
  61.  
  62. PROCEDURE InitTables();
  63. (* Tabellen initialisieren: *) 
  64. VAR 
  65. (*$Reg *) i : SHORTCARD; 
  66. BEGIN (* Init *) 
  67.   (* Sequence- und Translationtable l”schen: *) 
  68.   FOR i := 0 TO cMaxSequence     DO SeqTable[i].len := 0   END; 
  69.   FOR i := 0 TO cMaxTranslations DO TransTable[i].len := 0 END; 
  70.   CharPos := 0; 
  71. END InitTables;
  72.  
  73. VAR hz200 : LONGCARD;
  74.  
  75. PROCEDURE T200Hz () : LONGCARD;
  76. BEGIN
  77.   RETURN SysUtil1.SuperLPeek(SysVars._hz_200);
  78. END T200Hz;
  79.  
  80. PROCEDURE Error (Err: tResponse);
  81. (* Ausgabe eines Fehlers; die globale Variable 'Response' wird gesetzt und
  82.    die benutzerdefinierbare Fehlerfunktion wird aufgerufen.
  83.  *) 
  84.   VAR voidO : BOOLEAN;
  85. BEGIN 
  86.   Response := Err; 
  87.   voidO := ErrorProc(Err); 
  88. END Error;
  89.  
  90. PROCEDURE QError (Err: tResponse): BOOLEAN;
  91. (* Ausgabe eines Fehlers; die globale Variable 'Response' wird gesetzt und
  92.    die benutzerdefinierbare Fehlerfunktion wird aufgerufen.
  93.  *) 
  94. BEGIN 
  95.   Response := Err; 
  96.   RETURN ErrorProc(Err) 
  97. END QError;
  98.  
  99. PROCEDURE DummyError(Err: tResponse): BOOLEAN;
  100. (* Einfachste Form einer Fehlerbehandlung ist die: nichts tun *) 
  101. BEGIN 
  102.   RETURN TRUE 
  103. END DummyError;
  104.  
  105. PROCEDURE Out(ch: CHAR);
  106. (*  Ausgabe eines einzelnen Zeichens; es wird VOR der Ausgabe geprft, ob der
  107.  *  Kanal berhaupt 'ready' ist.
  108.  *)
  109. VAR
  110. (*$Reg *) Ok,
  111. (*$Reg *) Cancel: BOOLEAN;
  112. (*$Reg *) Timer : LONGCARD;
  113.           len   : LONGCARD;
  114. BEGIN (* Out *)
  115.   REPEAT
  116.     Timer := 1000 + T200Hz();
  117.     IF currentOut = 2 THEN
  118.       REPEAT
  119.         Ok := MagicDOS.Cauxos()
  120.       UNTIL Ok OR (Timer < T200Hz());
  121.       IF NOT Ok THEN
  122.         Cancel := NOT QError(AuxDeviceBusy)
  123.       END;
  124.     ELSIF currentOut = 3 THEN
  125.       REPEAT
  126.         Ok := MagicDOS.Cprnos();
  127.       UNTIL Ok OR (Timer < T200Hz());
  128.       IF NOT Ok THEN
  129.         Cancel := NOT QError(PrnDeviceBusy)
  130.        END;
  131.     ELSE
  132.       Ok := TRUE
  133.     END;
  134.   UNTIL Ok OR Cancel;
  135.  
  136.   IF Ok THEN
  137.     len := 1;
  138.     MagicDOS.Fwrite (PrnHdl, len, ADR(ch));
  139.     IF len = 1 THEN 
  140.       Response := done; 
  141.     ELSE
  142.       IF currentOut = 2
  143.       THEN
  144.         Cancel := NOT QError (AuxDeviceBusy)
  145.       ELSIF currentOut = 3
  146.       THEN
  147.         Cancel := NOT QError (PrnDeviceBusy)
  148.       ELSE
  149.         Cancel := TRUE;
  150.       END;
  151.       IF Cancel
  152.       THEN 
  153.         Error (Cancelled);
  154.       END;
  155.     END;
  156.   ELSE
  157.     Error(Cancelled)
  158.   END;
  159. END Out;
  160.  
  161.  
  162. PROCEDURE FreeCFGFile();
  163. (* L”scht eine bereits geladene CFG-Datei aus dem Speicher
  164.  *)
  165. BEGIN
  166.   IF CFG <> NIL THEN 
  167.     (* noch ein Printertreiber eingeh„ngt; ganz frech einfach freigeben: *) 
  168.     Storage.DEALLOCATE(CFG, 0); 
  169.   END; (* IF CFG <> NIL *) 
  170. END FreeCFGFile;
  171.  
  172. PROCEDURE LoadCFGFile(VAR name: ARRAY OF CHAR);
  173. (* Er”ffnung einer CFG-Datei. Der komplette Dateiname muž bergeben werden.
  174.    Falls keine Er”ffnung m”glich war, wird 'Response' auf 'CFGnotFound' gesetzt.
  175.    Die Datei wird nach Er”ffnung auf die Dateikennung in den ersten 8 Bytes
  176.    berprft ('GST-CFG:'). Falls die Kennung nicht bereinstimmt, wird
  177.    die Datei wieder geschlossen und 'Response' auf 'wrongIdent' gesetzt.
  178.    Im Erfolgsfall enth„lt 'Response' dann 'done'.
  179. *) 
  180. VAR     f       : SHORTINT; 
  181.         DOSRet, 
  182.         Length  : LONGCARD;                  (* nimmt die Dateil„nge auf. *) 
  183.         cKennung, 
  184.         Kennung : ARRAY[0..8] OF CHAR; 
  185.         res     : SHORTINT;
  186.         voidO   : BOOLEAN;
  187. (*$Reg *) i, 
  188. (*$Reg *) j, 
  189. (*$Reg *) Pos, 
  190. (*$Reg *) Len : SHORTCARD;                     (* Schleifenvariable         *) 
  191. BEGIN (* LoadCFGFile *) 
  192.   f := MagicDOS.Fopen(name, MagicDOS.Read); 
  193.   IF f < 0 THEN 
  194.     Error(CFGnotFound); 
  195.     RETURN; 
  196.   END; 
  197.  
  198.   IF CFG <> NIL THEN 
  199.     (* noch ein Printertreiber eingeh„ngt; ganz frech einfach freigeben: *) 
  200.     Storage.DEALLOCATE(CFG, 0); 
  201.   END; (* IF CFG <> NIL *) 
  202.  
  203.   Length := MagicDOS.Fseek(0, f, MagicDOS.SeekEnd); 
  204.  
  205.   Storage.ALLOCATE(CFG, Length); 
  206.   IF CFG = NIL THEN 
  207.     Error(noMemory); 
  208.     res := MagicDOS.Fclose(f); 
  209.     RETURN; 
  210.   END; 
  211.   InitTables(); 
  212.  
  213.   DOSRet := MagicDOS.Fseek(0, f, MagicDOS.SeekStart); 
  214.   MagicDOS.Fread(f, Length, ADR(CFG^)); 
  215.   res := MagicDOS.Fclose(f); 
  216.  
  217.   (* Kennung berprfen: *) 
  218.   cKennung := "GST-CFG:";   (* Kennung einer GST-Datei *) 
  219.   Strings.Copy(CFG^, 0, 8, Kennung, voidO); 
  220.   IF ~Strings.StrEqual (Kennung, cKennung) THEN 
  221.     Error(wrongIdent); (* Keine GST-CFG-Datei !!! *) 
  222.     RETURN; 
  223.   END; 
  224.   (* Jetzt mssen die Tabellen aufgebaut werden: *) 
  225.   i := 8; (* Lesezeiger auf den Beginn des Druckernamens setzen:  *) 
  226.   REPEAT 
  227.     INC(i) 
  228.   UNTIL CFG^[i] = 0C; (* Ende des Druckernamens gefunden. *) 
  229.  
  230.   INC(i, 7); (* Druckeranpassungen interessieren nicht.  *) 
  231.  
  232.   (* zun„chst die Tabelle der Druckerbesonderheiten:  *) 
  233.   WHILE CFG^[i] <> 0C DO (* Tabelle wird mit einem NUL-Byte beendet *) 
  234.     Len := ORD(CFG^[i]); 
  235.     Pos := ORD(CFG^[i+1]);  (* Tabelleneintrag *) 
  236.     WITH SeqTable[Pos] DO 
  237.       len  := Len - 2; 
  238.       pos  := i+2; 
  239.     END; 
  240.     INC(i, Len); 
  241.   END; (* WHILE CFG^[i] <> 0C *) 
  242.  
  243.   INC(i); (* Tabellenende berspringen *) 
  244.   (* jetzt die šbersetzungsTabelle:  *) 
  245.   WHILE CFG^[i] <> 0C DO (* Tabelle wird mit einem NUL-Byte beendet *) 
  246.     Len := ORD(CFG^[i]); 
  247.     Pos := ORD(CFG^[i+1]);  (* Tabelleneintrag *) 
  248.     WITH TransTable[Pos] DO 
  249.       IF Len >= 2
  250.       THEN 
  251.         len  := Len - 2; 
  252.       ELSE
  253.         len := 0;
  254.       END;
  255.       pos  := i+2; 
  256.     END; 
  257.     INC(i, Len); 
  258.   END; (* WHILE CFG^[i] <> 0C *) 
  259.  
  260.   (* Optimierung der Druckercharakteristik-Tabelle: *) 
  261.   (* 1. die Texteffekte: *) 
  262.   FOR i := cBold TO cUnderline BY 4 DO 
  263.     FOR j := i TO i+1 DO 
  264.       IF (SeqTable[j].len = 0) AND (SeqTable[j+2].len <> 0) THEN 
  265.         SeqTable[j] := SeqTable[j+2] 
  266.       END; 
  267.      IF (SeqTable[j+2].len = 0) AND (SeqTable[j].len <> 0) THEN 
  268.         SeqTable[j+2] := SeqTable[j] 
  269.       END; 
  270.    END; 
  271.   END; 
  272.   (* 2. die Schriftarten: *) 
  273.   FOR i := c1stType TO c1stType + 6 BY 2 DO 
  274.     IF (SeqTable[i].len = 0) AND (SeqTable[i+1].len <> 0) THEN 
  275.       SeqTable[i] := SeqTable[i+1] 
  276.     END; 
  277.    IF (SeqTable[i+1].len = 0) AND (SeqTable[i].len <> 0) THEN 
  278.       SeqTable[i+1] := SeqTable[i] 
  279.     END; 
  280.   END; 
  281.   Response := done; 
  282. END LoadCFGFile;
  283.  
  284.  
  285. PROCEDURE QueryCFGFile(VAR path, name    : ARRAY OF CHAR;
  286.                        REF InfoText: ARRAY OF CHAR);
  287. (* erfragt eine CFG-Datei per FileSelectBox.
  288.    InfoText ist fr die FileSelectBox gedacht.
  289.    Die Endung wird fest auf '*.CFG' festgeschrieben.
  290. *) 
  291.   VAR fullname : ARRAY [0..255] OF CHAR;
  292.       voidO    : BOOLEAN;
  293. BEGIN (* QueryCFGFile *) 
  294.   IF CatGlobal.FselGet (path, name, '*.cfg', InfoText, FALSE) THEN 
  295.     Strings.Concat (path, name, fullname, voidO);
  296.     LoadCFGFile(fullname); 
  297.   END; (* IF FSelect.Input(name, '*.cfg', InfoText *) 
  298. END QueryCFGFile;
  299.  
  300.  
  301. PROCEDURE GetPrnName(VAR Printername: ARRAY OF CHAR);
  302. (* Eingetragenen Druckernamen liefern. Falls keiner vorhanden ist, dann
  303.    wird ein Leerstring ('') geliefert.
  304.  *) 
  305. VAR 
  306. (*$Reg *) i : SHORTINT; 
  307. BEGIN (* GetPrnName *) 
  308.   IF CFG # NIL THEN 
  309.     i := 8; 
  310.     WHILE CFG^[i] <> 0C DO 
  311.       Printername[i-8] := CFG^[i]; 
  312.       INC(i); 
  313.     END; 
  314.     Printername[i-8] := 0C; 
  315.   ELSE 
  316.     Printername[0] := "" 
  317.   END; 
  318. END GetPrnName;
  319.  
  320.  
  321. PROCEDURE PrintSeq(Which: SHORTINT); 
  322. VAR (*$Reg *) i: SHORTINT; 
  323. BEGIN (* PrintSeq *) 
  324.   WITH SeqTable[Which] DO 
  325.     FOR i := pos TO pos + len - 1 DO 
  326.       Out(CFG^[i]); 
  327.       IF Response # done THEN RETURN END; 
  328.     END; 
  329.   END; (* WITH SeqTable[Which] *) 
  330. END PrintSeq;
  331.  
  332.  
  333. PROCEDURE Print(Entry: SHORTINT; Set : BOOLEAN);
  334. (*  Ausgabe der angew„hlten Steuersequenz. *) 
  335. BEGIN (* Print *) 
  336.   IF NOT Set THEN 
  337.     INC(Entry); 
  338.   END; 
  339.   PrintSeq(Entry + NLQSet); 
  340. END Print;
  341.  
  342.  
  343. PROCEDURE SendExit(); 
  344. BEGIN (* SendReset *) 
  345.   PrintSeq(cPrinterInit); 
  346. END SendExit;
  347.  
  348.  
  349. PROCEDURE SendInit(NLQ: BOOLEAN; hAndVInit : BOOLEAN);     (* Drucker initialisieren             *) 
  350. BEGIN (* SendInit *) 
  351.   NLQSet := 0; 
  352.   IF NLQ THEN 
  353.     NLQSet := 2; 
  354.   END; 
  355.   IF hAndVInit
  356.   THEN
  357.     PrintSeq(cHorzInit);        (* Horizontale Initialisierung *) 
  358.     IF Response # done THEN RETURN END; 
  359.     PrintSeq(cVertInit);        (* Vertikale Initialisierung   *) 
  360.     IF Response # done THEN RETURN END; 
  361.   END;
  362.   Print(cBold, FALSE);        (* Fettschrift aus.            *) 
  363.   IF Response # done THEN RETURN END; 
  364.   Print(cItalic, FALSE);      (* Kursivschrift aus.          *) 
  365.   IF Response # done THEN RETURN END; 
  366.   Print(cLight, FALSE);       (* Light aus.                  *) 
  367.   IF Response # done THEN RETURN END; 
  368.   Print(cSuperscript, FALSE); (* Superscript aus.            *) 
  369.   IF Response # done THEN RETURN END; 
  370.   Print(cSubscript, FALSE);   (* Subscript aus.              *) 
  371.   IF Response # done THEN RETURN END; 
  372.   Print(cUnderline, FALSE);   (* Unterstreichung aus.        *) 
  373.   IF Response # done THEN RETURN END; 
  374.  
  375.   AktMode  := -1; 
  376.   PrintSeq(c1stType);         (* PICA (10 CPI)               *) 
  377.   IF Response # done THEN RETURN END; 
  378.   AktColor := -1; 
  379.   PrintSeq(c1stColor);        (* Color-Einstellung: Black.   *) 
  380.   IF Response # done THEN RETURN END; 
  381.   Proportional := FALSE; 
  382.   PrintSeq(cProp + 1);        (* Proportional-Schrift aus.   *) 
  383. END SendInit;
  384.  
  385.  
  386. PROCEDURE Bold(Set: BOOLEAN);         (* Fettdruck ein/ausschalten          *) 
  387. BEGIN (* Bold *) 
  388.   Print(cBold, Set); 
  389. END Bold;
  390.  
  391. PROCEDURE Italic(Set: BOOLEAN);       (* Schr„gschrift ein/ausschalten      *) 
  392. BEGIN (* Italic *) 
  393.   Print(cItalic, Set); 
  394. END Italic;
  395.  
  396. PROCEDURE Light(Set: BOOLEAN);        (* Helle Schrift ein/ausschalten      *) 
  397. BEGIN (* Light *) 
  398.   Print(cLight, Set); 
  399. END Light;
  400.  
  401. PROCEDURE Superscript(Set: BOOLEAN);  (* Hochstellen ein/ausschalten        *) 
  402. BEGIN (* Superscript *) 
  403.   Print(cSuperscript, Set); 
  404. END Superscript;
  405.  
  406. PROCEDURE Subscript(Set: BOOLEAN);    (* Tiefstellen ein/ausschalten        *) 
  407. BEGIN (* Subscript *) 
  408.   Print(cSubscript, Set); 
  409. END Subscript;
  410.  
  411. PROCEDURE Underline(Set: BOOLEAN);    (* Unterstreichen ein/ausschalten     *) 
  412. BEGIN (* Underline *) 
  413.   Print(cUnderline, Set); 
  414. END Underline;
  415.  
  416. PROCEDURE Effect(Effects: BITSET; Set: BOOLEAN);
  417. (* Texteffekte setzen/rcksetzen *) 
  418. VAR (*$Reg *) i : SHORTCARD; 
  419. BEGIN (* Effect *) 
  420.   FOR i := cFat TO cUnderlined DO 
  421.     IF i IN Effects THEN 
  422.       CASE i OF 
  423.         cFat        : Bold(Set); 
  424.       | cLightened  : Light(Set); 
  425.       | cSlanted    : Italic(Set); 
  426.       | cUnderlined : Underline(Set); 
  427.       ELSE 
  428.       END; 
  429.     END; 
  430.   END; 
  431. END Effect;
  432.  
  433.  
  434. PROCEDURE FormFeed();
  435. (*  Seitenvorschub ausgeben *) 
  436. BEGIN (* FormFeed *) 
  437.   IF CFG # NIL  
  438.   THEN
  439.     PrintSeq(cFormFeed); 
  440.     CharPos := 0;
  441.   ELSE
  442.     Write (14C);
  443.     CharPos := 0;
  444.   END;
  445. END FormFeed;
  446.  
  447. PROCEDURE SetTabSize(Tab: SHORTINT); 
  448. BEGIN (* SetTabSize *) 
  449.   TabSize := Tab; 
  450. END SetTabSize;
  451.  
  452. PROCEDURE SetPropSize(Prop: BOOLEAN; PSize: SHORTINT);
  453. (* Ein/Ausschalten der Proportionalschrift sowie Setzen einer mittleren
  454.    Zeichenbreite (fr Tabulierung notwendig)
  455. *) 
  456. VAR (*$Reg *) nlq : SHORTINT; 
  457. BEGIN (* SetPropSize *) 
  458.   nlq := NLQSet; 
  459.   NLQSet := 0; 
  460.   Print(cProp, Prop); 
  461.   NLQSet := nlq; 
  462.   PropSize := PSize; 
  463.   Proportional := Prop; 
  464. END SetPropSize;
  465.  
  466. PROCEDURE WriteLn();
  467. (*  Zeilenvorschub ausgeben *)
  468. BEGIN (* WriteLn *)
  469.   IF CFG # NIL
  470.   THEN
  471.     PrintSeq(cWriteLn);
  472.     CharPos := 0;
  473.   ELSE
  474.     Write (15C);
  475.     Write (12C);
  476.     CharPos := 0;
  477.   END;
  478. END WriteLn;
  479.  
  480. PROCEDURE SetMode(Mode : SHORTINT);
  481. (*  Zeichenbreite einstellen.
  482.     ACHTUNG: vorher Druckmodus 'DRAFT' oder 'NLQ' einstellen!
  483.  *) 
  484. BEGIN (* SetMode *) 
  485.   IF (Mode >= cPica) AND (Mode <= cExpanded) THEN 
  486.     IF Mode <> AktMode THEN 
  487.       PrintSeq(2 * Mode + c1stType + (NLQSet DIV 2)); 
  488.       AktMode := Mode; 
  489.     END; 
  490.   END; 
  491. END SetMode;
  492.  
  493. PROCEDURE SetColor(Color : SHORTINT);
  494. (*  Farbe einstellen. *) 
  495. BEGIN (* SetColor *) 
  496.   IF (Color >= cBlack) AND (Color <= cYellow) THEN 
  497.     IF Color <> AktColor THEN 
  498.       PrintSeq(Color + c1stColor); 
  499.       AktColor := Color; 
  500.     END; 
  501.   END; 
  502. END SetColor;
  503.  
  504. PROCEDURE SetHead();
  505. (*  Druckkopf neu positionieren *) 
  506. VAR 
  507. (*$Reg *) i : SHORTINT; 
  508. BEGIN (* SetHead *) 
  509.   WITH SeqTable[cVertPos] DO 
  510.     FOR i := pos TO pos + len - 1 DO 
  511.       IF CFG^[i] = CHAR(80H) THEN 
  512.         Out(CHR((CharPos * 60 DIV PropSize) MOD 256)) 
  513.       ELSIF CFG^[i] = CHAR(81H) THEN 
  514.         Out(CHR((CharPos * 60 DIV PropSize) DIV 256)) 
  515.       ELSE 
  516.         Out(CFG^[i]); 
  517.       END; 
  518.     END; (* FOR i := pos ... *) 
  519.   END; (* WITH SeqTable[cVertPos] *) 
  520.   NrSpaces := 0; 
  521. END SetHead;
  522.  
  523. PROCEDURE WriteChar(ch: CHAR); 
  524. VAR 
  525. (*$Reg *) i : SHORTINT; 
  526. BEGIN (* *) 
  527.   WITH TransTable[ORD(ch)] DO 
  528.     IF len > 0 THEN 
  529.       FOR i := pos TO pos + len - 1 DO 
  530.         Out(CFG^[i]); 
  531.         IF Response # done THEN RETURN END; 
  532.       END; 
  533.       INC(CharPos); 
  534.     ELSE 
  535.       Out(ch); (* Zeichen ohne šbersetzung ausgeben. *) 
  536.       INC(CharPos); 
  537.     END; 
  538.   END; (* WITH TransTable[ORD(ch)] *) 
  539. END WriteChar;
  540.  
  541. PROCEDURE Write(ch: CHAR);
  542. (*  Zentrale Prozedur fr die šbersetzung der einzelnen Zeichen in eine
  543.     Zeichenfolge.
  544.  *) 
  545. VAR (*$Reg *) i : SHORTINT; 
  546. BEGIN (* Write *) 
  547.   IF (ch = cTab) OR (ch = ' ') THEN 
  548.     IF Proportional THEN 
  549.       IF ch = ' ' THEN 
  550.         INC(CharPos); 
  551.         INC(NrSpaces); 
  552.       ELSE 
  553.         INC(CharPos,  TabSize); 
  554.         INC(NrSpaces, TabSize); 
  555.       END; 
  556.     ELSE 
  557.       IF ch = ' ' THEN 
  558.         WriteChar(' ') 
  559.       ELSE 
  560.         FOR i := 1 TO TabSize DO 
  561.           WriteChar(' '); 
  562.           IF Response # done THEN RETURN END; 
  563.         END; 
  564.       END; 
  565.     END; 
  566.   ELSE 
  567.     IF NrSpaces > 1 THEN 
  568.       SetHead(); 
  569.     ELSIF NrSpaces = 1 THEN 
  570.       WriteChar(' '); 
  571.       NrSpaces := 0; 
  572.     END; 
  573.     WriteChar(ch); 
  574.   END; 
  575. END Write;
  576.  
  577. PROCEDURE WriteString(REF Str: ARRAY OF CHAR); 
  578. VAR (*$Reg *) i : SHORTINT; 
  579. BEGIN (* WriteString *) 
  580.   i := 0; 
  581.   WHILE Str[i] <> 0C DO 
  582.     Write(Str[i]); 
  583.     IF Response # done THEN RETURN END; 
  584.     INC(i) 
  585.   END; 
  586. END WriteString;
  587.  
  588. PROCEDURE Open(REF Name: ARRAY OF CHAR);
  589. (* Er”ffnung eines Druckerkanals; wenn ein Fehler auftritt, wird 'Response'
  590.    auf 'ErrorInStreams' gestellt; die eigentliche Fehlerursache ist dann bei
  591.    'Streams.Response' zu suchen.
  592. *) 
  593. VAR (*$Reg *) i, 
  594.     (*$Reg *) Device: SHORTINT; 
  595.             str   : ARRAY[0..3] OF CHAR; 
  596. BEGIN (* Open *) 
  597.   Response := done; 
  598.  
  599.   (* Zum Stringvergleich die 3 ersten Zeichen kapitalisieren: *) 
  600.   FOR i := 0 TO 3 DO 
  601.     IF Name[i] <> 0C THEN str[i] := CAP(Name[i]) END; 
  602.   END; 
  603.   Device := 0; 
  604.   IF LONGCARD(str)=LONGCARD(cCon) THEN Device := 1 END; 
  605.   IF LONGCARD(str)=LONGCARD(cAux) THEN Device := 2 END; 
  606.   IF LONGCARD(str)=LONGCARD(cPrn) THEN Device := 3 END; 
  607.  
  608.   IF Device = 0 THEN     (* Wird wohl ein File sein *)
  609.     PrnHdl := MagicDOS.Fcreate (Name, {});
  610.   ELSE 
  611.     PrnHdl := MagicDOS.Fopen (Name, {MagicDOS.Write});
  612.   END; 
  613.   IF PrnHdl < 0
  614.   THEN
  615.     IF PrnHdl # -Device THEN 
  616.       Error(ErrorInStreams) 
  617.     END;
  618.   END;
  619. END Open;
  620.  
  621. PROCEDURE Close();
  622. (* Schliežung eines Druckerkanals; wenn ein Fehler auftritt, wird 'Response'
  623.    auf 'ErrorInStreams' gestellt; die eigentliche Fehlerursache ist dann bei
  624.    'Streams.Response' zu suchen.
  625. *) 
  626.   VAR res : INTEGER;
  627. BEGIN (* Close *) 
  628.   res := MagicDOS.Fclose (PrnHdl);
  629.   (*
  630.   IF Streams.currentOut > 3 THEN 
  631.     Streams.Close(PrnHdl); 
  632.   ELSE 
  633.     Streams.StdOutputProc(Streams.currentOut); 
  634.   END; 
  635.   IF Streams.Response <> Streams.done THEN 
  636.     Error(ErrorInStreams); 
  637.   ELSE 
  638.     Response := done 
  639.   END; 
  640.   *)
  641. END Close;
  642.  
  643. BEGIN
  644.   ErrorProc := DummyError;
  645.   CFG       := NIL;     (* Zeiger auf die CFG-Informationen initialisieren. *)
  646.   NLQSet    := 0;       (* Schriftqualit„t auf Draft. *)
  647.   TabSize   := 8;       (* Standard-Tabweite *)
  648.   NrSpaces  := 0;
  649.   InitTables();
  650. END Printer.
  651.  
  652.